package work.mediway.mdm.biz.job;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorCompletionService;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import work.mediway.mdm.core.thread.DimplesTaskExecutor;
import work.mediway.mdm.core.enums.DataQualityVerifyEnum;
import work.mediway.mdm.core.exception.BizException;
import work.mediway.mdm.biz.dto.biz.DataQualityVerifyDTO;
import work.mediway.mdm.biz.entity.biz.SsDataQualityConfig;
import work.mediway.mdm.biz.service.biz.SsDataQualityConfigService;

/**
 * 数据质量任务
 *
 * @author zhongyj <1126834403@qq.com><br/>
 * @date 2022/7/27
 */
@Slf4j
//@Component
@RequiredArgsConstructor
public class DataQualityJob {

    private final SsDataQualityConfigService dataQualityConfigService;

    /**
     * 执行任务，根据jobId筛选
     *
     * @param jobId String
     */
    public void execute(String jobId) {
        LambdaQueryWrapper<SsDataQualityConfig> queryWrapper = Wrappers.lambdaQuery(SsDataQualityConfig.class)
                .eq(SsDataQualityConfig::getNumberComparisonCycle, jobId);
        List<SsDataQualityConfig> numberComparison = this.dataQualityConfigService.list(queryWrapper);
        List<Callable<Object>> task = CollUtil.newArrayList();
        if (CollUtil.isNotEmpty(numberComparison)) {
            for (SsDataQualityConfig ssDataQualityConfig : numberComparison) {
                task.add(() -> {
                    DataQualityVerifyDTO qualityVerifyDTO = new DataQualityVerifyDTO();
                    qualityVerifyDTO.setConfigId(String.valueOf(ssDataQualityConfig.getId()));
                    qualityVerifyDTO.setDataQualityVerifyEnum(CollUtil.newArrayList(DataQualityVerifyEnum.N));
                    this.dataQualityConfigService.startDataQuality(CollUtil.newArrayList(qualityVerifyDTO));
                    return true;
                });
            }
        }

        queryWrapper.clear();
        queryWrapper.eq(SsDataQualityConfig::getContentComparisonCycle, jobId);
        List<SsDataQualityConfig> contentComparison = this.dataQualityConfigService.list(queryWrapper);
        if (CollUtil.isNotEmpty(contentComparison)) {
            for (SsDataQualityConfig ssDataQualityConfig : contentComparison) {
                task.add(() -> {
                    DataQualityVerifyDTO qualityVerifyDTO = new DataQualityVerifyDTO();
                    qualityVerifyDTO.setConfigId(String.valueOf(ssDataQualityConfig.getId()));
                    qualityVerifyDTO.setDataQualityVerifyEnum(CollUtil.newArrayList(DataQualityVerifyEnum.C));
                    qualityVerifyDTO.setStartDate(DateUtil.formatDateTime(DateUtil.offsetDay(DateUtil.parseDateTime(DateUtil.now()), Integer.parseInt(ssDataQualityConfig.getTaskDateRange()))));
                    qualityVerifyDTO.setEndDate(DateUtil.now());
                    this.dataQualityConfigService.startDataQuality(CollUtil.newArrayList(qualityVerifyDTO));
                    return true;
                });
            }
        }

        if (CollUtil.isNotEmpty(task)) {
            List<List<Callable<Object>>> partition = ListUtil.partition(task, 5);
            DimplesTaskExecutor<Object> taskExecutor = new DimplesTaskExecutor<>();
            ExecutorCompletionService<Object> completionService = taskExecutor.getCompletionService();
            for (List<Callable<Object>> callables : partition) {
                for (Callable<Object> callable : callables) {
                    completionService.submit(callable);
                }
                for (int i = 0; i < callables.size(); i++) {
                    try {
                        completionService.take().get();
                    } catch (Exception e) {
                        throw new BizException("定时任务-数据质量", e);
                    }
                }
            }
        }
    }
}
